home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Examples / LazyScrollDir / DirArray.m < prev    next >
Encoding:
Text File  |  1996-02-08  |  8.2 KB  |  327 lines

  1. //=============================================================================
  2. //
  3. //        Copyright (C) 1995,1996 by Paul S. McCarthy and Eric Sunshine.
  4. //                Written by Paul S. McCarthy and Eric Sunshine.
  5. //                            All Rights Reserved.
  6. //
  7. //        This notice may not be removed from this source code.
  8. //
  9. //        This object is included in the MiscKit by permission from the authors
  10. //        and its use is governed by the MiscKit license, found in the file
  11. //        "License.rtf" in the MiscKit distribution.    Please refer to that file
  12. //        for a list of all applicable permissions and restrictions.
  13. //
  14. //=============================================================================
  15. //-----------------------------------------------------------------------------
  16. // DirArray.m
  17. //
  18. //        An extensible array of directory entries.
  19. //
  20. //-----------------------------------------------------------------------------
  21. //-----------------------------------------------------------------------------
  22. // $Id$
  23. // $Log$
  24. //-----------------------------------------------------------------------------
  25. #import "DirArray.h"
  26. #import <appkit/appkit.h>
  27. #import <assert.h>
  28.  
  29.  
  30. @implementation DirArray
  31.  
  32. //-----------------------------------------------------------------------------
  33. // safeStrdup
  34. //-----------------------------------------------------------------------------
  35. - (char*) safeStrdup:(char const*)s
  36.     {
  37.     char* t = 0;
  38.     if (s != 0)
  39.         t = NXCopyStringBufferFromZone( s, [self zone] );
  40.     return t;
  41.     }
  42.  
  43.  
  44. //-----------------------------------------------------------------------------
  45. // safeFree
  46. //-----------------------------------------------------------------------------
  47. - (void) safeFree:(void*)p
  48.     {
  49.     if (p != 0)
  50.         NXZoneFree( [self zone], p );
  51.     }
  52.  
  53.  
  54. //-----------------------------------------------------------------------------
  55. // dirEntryCons
  56. //-----------------------------------------------------------------------------
  57. - (void) dirEntryCons: (DirEntry*) de
  58.     name: (char const*) n
  59.     path: (char const*) path
  60.     {
  61.     int rc;
  62.     memset( de, 0, sizeof(*de) );
  63.  
  64.     de->dir = self;
  65.     de->name = [self safeStrdup:n];
  66.  
  67.     if ((rc = lstat( path, &(de->st) )) == 0)
  68.         {
  69.         if ((de->st.st_mode & S_IFMT) == S_IFLNK)        // soft-link?
  70.             {
  71.             char symbuf[ FILENAME_MAX + 1 ];
  72.             int cc;
  73.             cc = readlink( path, symbuf, FILENAME_MAX );
  74.             if (cc >= 0)
  75.                 {
  76.                 symbuf[ cc ] = '\0';
  77.                 de->soft_link = [self safeStrdup:symbuf];
  78.                 rc = stat( path, &(de->st) );
  79.                 }
  80.             else
  81.                 rc = -1;
  82.             }
  83.         }
  84.  
  85.     if (rc != 0)
  86.         de->err = errno;
  87.     }
  88.  
  89.  
  90. //-----------------------------------------------------------------------------
  91. // dirEntryDestroy:
  92. //-----------------------------------------------------------------------------
  93. - (void) dirEntryDestroy:(DirEntry*)de
  94.     {
  95.     if (de->image != 0)
  96.         [de->image free];
  97.     [self safeFree:de->name];
  98.     [self safeFree:de->soft_link];
  99.     }
  100.  
  101.  
  102. //-----------------------------------------------------------------------------
  103. // entryAt:
  104. //-----------------------------------------------------------------------------
  105. - (DirEntry const*)entryAt:(int)n
  106.     {
  107.     assert( 0 <=n && n < num_entries );
  108.     return (entries + n);
  109.     }
  110.  
  111.  
  112. //-----------------------------------------------------------------------------
  113. // isDir:
  114. //-----------------------------------------------------------------------------
  115. - (BOOL) isDir:(DirEntry const*)de
  116.     {
  117.     return ((de->st.st_mode & S_IFMT) == S_IFDIR);
  118.     }
  119.  
  120.  
  121. //-----------------------------------------------------------------------------
  122. // isDirAt:
  123. //-----------------------------------------------------------------------------
  124. - (BOOL) isDirAt:(int)n
  125.     {
  126.     return [self isDir:[self entryAt:n]];
  127.     }
  128.  
  129.  
  130. //-----------------------------------------------------------------------------
  131. // loadImage:
  132. //-----------------------------------------------------------------------------
  133. - (NXImage*) loadImage:(DirEntry*)de
  134.     {
  135.     char buff[ FILENAME_MAX + 1 ];
  136.     char const* const dir_part = de->dir->name;
  137.     int const dirlen = strlen( dir_part );
  138.     memcpy( buff, dir_part, dirlen );
  139.     strcpy( buff + dirlen, de->name );
  140.     de->image = [[Application workspace] getIconForFile: buff];
  141.     [de->image setScalable: YES];
  142.     return de->image;
  143.     }
  144.  
  145.  
  146. //-----------------------------------------------------------------------------
  147. // getImage:
  148. //-----------------------------------------------------------------------------
  149. - (NXImage*) getImage:(DirEntry const*)de
  150.     {
  151.     if (de->image == 0)
  152.         [self loadImage:(DirEntry*)de];
  153.     return de->image;
  154.     }
  155.  
  156.  
  157. //-----------------------------------------------------------------------------
  158. // getImageAt:
  159. //-----------------------------------------------------------------------------
  160. - (NXImage*) getImageAt:(int)n
  161.     {
  162.     return [self getImage:[self entryAt:n]];
  163.     }
  164.  
  165.  
  166. //-----------------------------------------------------------------------------
  167. // init
  168. //-----------------------------------------------------------------------------
  169. - init
  170.     {
  171.     [super init];
  172.     total_bytes = 0;
  173.     num_entries = 0;
  174.     max_entries = 0;
  175.     entries = 0;
  176.     return self;
  177.     }
  178.  
  179.  
  180. //-----------------------------------------------------------------------------
  181. // empty
  182. //-----------------------------------------------------------------------------
  183. - (void) empty
  184.     {
  185.     DirEntry* p;
  186.     for (p = entries + num_entries; p != entries; )
  187.         [self dirEntryDestroy:--p];
  188.     num_entries = 0;
  189.     total_bytes = 0;
  190.     }
  191.  
  192.  
  193. //-----------------------------------------------------------------------------
  194. // free
  195. //-----------------------------------------------------------------------------
  196. - free
  197.     {
  198.     [self empty];
  199.     [self safeFree:name];
  200.     [self safeFree:entries];
  201.     return [super free];
  202.     }
  203.  
  204.  
  205. //-----------------------------------------------------------------------------
  206. // count
  207. //-----------------------------------------------------------------------------
  208. - (int) count
  209.     {
  210.     return num_entries;
  211.     }
  212.  
  213.  
  214. //-----------------------------------------------------------------------------
  215. // totalBytes
  216. //-----------------------------------------------------------------------------
  217. - (int) totalBytes
  218.     {
  219.     return total_bytes;
  220.     }
  221.  
  222.  
  223. //-----------------------------------------------------------------------------
  224. // remove:
  225. //-----------------------------------------------------------------------------
  226. - (void) remove:(int)n
  227.     {
  228.     if (0 <= n && n < num_entries)
  229.         {
  230.         DirEntry* p = entries + n;
  231.         total_bytes -= p->st.st_size;
  232.         num_entries--;
  233.         [self dirEntryDestroy:p];
  234.         if (n < num_entries)
  235.             memmove( p, p + 1, (num_entries - n) * sizeof(*p) );
  236.         }
  237.     }
  238.  
  239.  
  240. //-----------------------------------------------------------------------------
  241. // expand
  242. //-----------------------------------------------------------------------------
  243. - (void) expand
  244.     {
  245.     DirEntry* p = entries;
  246.     int N = max_entries;
  247.     if (N == 0)
  248.         {
  249.         N = 16;
  250.         p = (DirEntry*) NXZoneMalloc( [self zone], N * sizeof(*p) );
  251.         }
  252.     else
  253.         {
  254.         N += N;
  255.         p = (DirEntry*) NXZoneRealloc( [self zone], p, N * sizeof(*p) );
  256.         }
  257.     max_entries = N;
  258.     entries = p;
  259.     }
  260.  
  261.  
  262. //-----------------------------------------------------------------------------
  263. // addName:path:
  264. //-----------------------------------------------------------------------------
  265. - (void) addName:(char const*)n path:(char const*)fullpath
  266.     {
  267.     DirEntry* p;
  268.     if (num_entries >= max_entries)
  269.         [self expand];
  270.     p = entries + num_entries++;
  271.     [self dirEntryCons:p name:n path:fullpath];
  272.     total_bytes += p->st.st_size;
  273.     }
  274.  
  275.  
  276. //-----------------------------------------------------------------------------
  277. // loadPath:showHidden:
  278. //-----------------------------------------------------------------------------
  279. - (int) loadPath:(char const*)path showHidden:(BOOL)showHidden
  280.     {
  281.     int rc = 0;
  282.     int dirlen;
  283.     DIR* dirp;
  284.     char namebuff[ FILENAME_MAX + 1 ];
  285.  
  286.     dirlen = strlen( path );
  287.     strcpy( namebuff, path );
  288.     if (dirlen == 0 || namebuff[ dirlen - 1 ] != '/')
  289.         {
  290.         namebuff[ dirlen++ ] = '/';
  291.         namebuff[ dirlen ] = '\0';
  292.         }
  293.  
  294.     [self empty];
  295.     [self safeFree:name];
  296.     name = [self safeStrdup:namebuff];
  297.  
  298.     if ((dirp = opendir( path )) != 0)
  299.         {
  300.         struct direct const* dp;
  301.  
  302.         while ((dp = readdir(dirp)) != 0)
  303.             {            // Do not include the "." (self) entry.
  304.             int const len = dp->d_namlen;
  305.             char const* const nam = dp->d_name;
  306.             BOOL const dot_name = (nam[0] == '.');
  307.             if ((len > 1 || !dot_name) &&        // exclude "."
  308.                 (showHidden || !dot_name ||
  309.                 (len == 2 && nam[1] == '.')))    // include ".."
  310.                 {
  311.                 memcpy( namebuff + dirlen, nam, len + 1 );
  312.                 [self addName:nam path:namebuff];
  313.                 }
  314.             }
  315.  
  316.         closedir( dirp );
  317.         }
  318.     else
  319.         {
  320.         rc = errno;
  321.         }
  322.  
  323.     return rc;
  324.     }
  325.  
  326. @end
  327.